之前在第 15 天的時候,我有提過希望可以把 build image 的步驟移到 CI pipeline 裡面,雖然本來想簡單比較一下各大 container registry 的,不過稍微翻了一下發現,直接使用 GitHub 或是 GitLab 提供的 container registry,那麼今天我就簡單來記錄一下如何設定 pipeline 吧。
因為目前 NOJ 是搬到自架的 GitLab 上面,所以這篇就來講講如何寫出一個可以 build image 的 CI job 吧。只要把下面這段貼到 .gitlab-ci.yml
就完成了~
build:
only:
variables:
- $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:latest
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG -f Dockerfile.prod .
- docker push $IMAGE_TAG
沒啦,當然是開玩笑的,雖然上面這段設定在官方文件就能找到,但我還是簡單講解一下這段邏輯吧。
首先看到 script
區段:
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
docker build -t $IMAGE_TAG -f Dockerfile.prod .
docker push $IMAGE_TAG
首先第一行的 docker login
就是要登入 registry,因為使用 GitLab CI 的關係,其實它都已經幫我們準備好相關的變數了(CI_REGISTRY
開頭的那些),所以就可以簡單的登入了。
接下來要 build,這邊跟官方文件唯一不同的地方是特別指定了使用 Dockerfile.prod
這個 production 用的 Dockerfile,因為預設的需要掛 volume 才能使用。
最後就是要用 docker push
把 image 推到 registry,這邊的 IMAGE_TAG
是在上面定義的,內容是 $CI_REGISTRY_IMAGE:latest
,CI_REGISTRY_IMAGE
也是 GitLab 預先提供的變數,長得會像是 registry.gitlab.com/<owner>/<project>
這樣的字串。
除了用 script
定義要執行的命令,我們還需要注意這裡要使用 docker
image,這樣才能正常的執行 docker cli 的命令,另外還需要設定一個 docker:*-dind
的容器作為 docker daemon,關於其他實現 DinD (Docker in Docker) 的方式,可以參考官方文件的說明還有這篇討論。
最後是那個 only
,因為我只需要它在 main branch 上面執行 build 就好,所以還需要定義條件,因為有用到 GitLab 的變數,所以要使用 only:variables
,而不是直接寫在 only
底下。